package com.yanqu.road.server.gameplayer.module.player;

import com.yanqu.road.dao.impl.player.UserCommonActivityDataDaoImpl;
import com.yanqu.road.entity.autodata.wealthscroll.WealthScrollUserData;
import com.yanqu.road.entity.activity.wealthscroll.config.WealthScrollTaskConfig;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.enums.activity.wealthscroll.eWealthScrollBuyLevel;
import com.yanqu.road.entity.log.wealthscroll.LogWealthScrollGetReward;
import com.yanqu.road.logic.activity.wealthscroll.WealthScrollConfig;
import com.yanqu.road.pb.activity.WealthScrollProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityMallModule;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.logic.activity.BaseActivityData;
import com.yanqu.road.server.logic.activity.condition.BaseActivityCondition;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.MultipleLanguageMgr;
import com.yanqu.road.server.manger.activity.wealthscroll.WealthScrollActivityMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.mina.util.ConcurrentHashSet;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 新财神密卷模块
 */

public class WealthScrollModule extends GeneralModule {

    private WealthScrollUserData userData;

    public WealthScrollModule(GamePlayer player) {
        super(player);
    }

    public void init(){
        syncConfig();
        checkWealthScrollUserData();
        checkNextNo();
        syncUserData();
    }

    /**
     * 初始化玩家数据
     */
    public synchronized void initUserData(int activityId) {
        if (userData != null) {
            if (userData.getActivityId() == activityId){
                return;
            }
        }
        WealthScrollUserData tmpUserData = new WealthScrollUserData();
        tmpUserData.setActivityId(activityId);
        tmpUserData.setUserId(getUserId());
        tmpUserData.setNo(1);
        tmpUserData.setStartTime(DateHelper.getTodayZeroTimeStamp());
        tmpUserData.setExp(0);

        tmpUserData.setHasGetReward(new ConcurrentHashSet<>());
        tmpUserData.setBuyType(new ConcurrentHashSet<>());
        tmpUserData.setRepeatBuyMap(new ConcurrentHashMap<>());

        tmpUserData.setUpdateTime(System.currentTimeMillis());
        tmpUserData.setLastRefreshConditionTime(DateHelper.getTodayZeroTimeStamp());

        tmpUserData.setInsertOption();

        userData = tmpUserData;
        return;
    }

    /**
     * 同步配置
     */

    public void syncConfig(){
        WealthScrollProto.WealthScrollConfigSync.Builder msgBuilder = WealthScrollActivityMgr.getConfigMsgBuilder();
        if (msgBuilder == null) {
            return;
        }
        player.sendPacket(ClientProtocol.U_WEALTH_SCROLL_CONFIG_SYNC, msgBuilder);
    }

    /**
     * 同步玩家数据
     */
    public void syncUserData() {
        if (userData == null) {
            return;
        }
        WealthScrollProto.WealthScrollUserDataSync.Builder sync = WealthScrollProto.WealthScrollUserDataSync.newBuilder();
        WealthScrollProto.WealthScrollUserDataMsg.Builder builder = parseUserDataMsg(userData);
        if (builder == null) {
            return;
        }
        sync.setData(builder);
        player.sendPacket(ClientProtocol.U_WEALTH_SCROLL_USER_DATA_SYNC, sync);
    }

    /**
     * 检测是否进入下一期密卷 或者刷新获得进度的任务
     */
    public synchronized void checkNextNo(){
        //没解锁不管
        if (!SystemOpenMgr.systemOpen(player, eSystemId.WealthScroll.getValue())){
            return;
        }

        if (userData == null) {
            return;
        }
        //活动没了
        if (!WealthScrollActivityMgr.isNewWealthScrollOpening()){
            return;
        }

        long now = System.currentTimeMillis();
        WealthScrollConfig config = WealthScrollActivityMgr.getConfig();
//        //如果换活动了
//        if (userData.getActivityId() != config.getActivityId()){
//            checkWealthScrollUserData();
//        }
//        //如果还是不对 不看了
//        if (userData.getActivityId() != config.getActivityId()){
//            return;
//        }

        //如果距离上次重置condition的时间已经跨周了
        if (!DateHelper.isSameWeekByMillis(now, userData.getLastRefreshConditionTime())){
            //重置condition
            resetUserCondition();
        }

        //如果当前这一期还没过期
        if ((userData.getStartTime() + (config.getSustainDay() * DateHelper.DAY_MILLIONS)) > now){
            return;
        }

        //-----------------------下面是过期了 需要进入到下一期的操作---------------------------
        List<Integer> autoSendList = new ArrayList<>();
        Property autoSendReward = new Property();
        //拿出玩家已领取过的奖励
        Set<Integer> hasGetReward = userData.getHasGetReward();
        //拿出所有配置的任务奖励 包括复购和进度奖励
        for (WealthScrollTaskConfig taskConfig:config.getTaskConfigMap().values()){
            //如果已经领奖就下一个
            if (hasGetReward.contains(taskConfig.getId())){
                continue;
            }
            //如果不能完成就下一个
            if (!canComplete(taskConfig)){
                continue;
            }
            //拿出奖励
            String configRewards = WealthScrollActivityMgr.getTaskRewardString(taskConfig, userData.getNo());

            if (StringUtils.isNullOrEmpty(configRewards)){
                log.error("奖励配置不存在,taskId {},userId{},no{}",taskConfig.getId(),getUserId(),userData.getNo());
                continue;
            }

            autoSendList.add(taskConfig.getId());
            autoSendReward.addProperty(PropertyHelper.parseStringToProperty(configRewards));

            //日志
            addGetRewardLog(taskConfig,config.getActivityId(),userData.getNo(),configRewards,2);
        }
        //下一期吧
        int nextWealthScrollNo = WealthScrollActivityMgr.getNextWealthScrollNo(userData.getNo());
        userData.setNo(nextWealthScrollNo);
        long todayZeroTimeStamp = DateHelper.getTodayZeroTimeStamp();
        if (nextWealthScrollNo == 0){
            userData.setStartTime(0);
        }else {
            userData.setStartTime(todayZeroTimeStamp);
        }
        //判断升降挡位
        for (eWealthScrollBuyLevel type:eWealthScrollBuyLevel.values()){
            if (type == eWealthScrollBuyLevel.free){
                continue;
            }
            //如果本期没买这个类型 复购降档
            if (!userData.getBuyType().contains(type.getValue())){
                userData.reduceRepeatBuyNum(type.getValue(),1,0);
            }
        }

        //exp清空
        userData.setExp(0);
        //已完成任务清空
        userData.setHasGetReward(new ConcurrentHashSet<>());
        //activity condition任务也要强制清空
        //重置condition
        resetUserCondition();

        //清空已购买的
        userData.clearBuyType();
        userData.setUpdateTime(now);

        userData.setUpdateOption();

        log.info("财神秘卷过期自动发奖：用户ID={}，期数={}，经验值={}，购买的等级={}，奖励={},补发的任务id{}",
                player.getUserId(), userData.getNo(), userData.getExp(), userData.getBuyType(), PropertyHelper.parsePropertyToString(autoSendReward),autoSendList);

        //如果有补发道具
        if (!autoSendReward.isNothing()){
            String mailTitle = MultipleLanguageMgr.getContent(MailManager.SECRET_VOLUME_AUTO_SEND_REWARD_TITLE, player.getLanguage());
            String mailContent = MultipleLanguageMgr.getContent(MailManager.SECRET_VOLUME_AUTO_SEND_REWARD_CONTENT, player.getLanguage());
            MailManager.sendMailOnLoad(player, eMailType.SYSTEM.getValue(), PropertyHelper.parsePropertyToString(autoSendReward), mailContent, mailTitle);
        }

        //清空限购
        player.getModule(ActivityMallModule.class).resetCustomMall(eShopType.WealthScrollMall.getValue(),todayZeroTimeStamp);
        syncUserData();
    }

    //重置财神密卷活动的condition进度任务8
    public void resetUserCondition(){
        boolean resetWealthScrollTaskCondition = resetWealthScrollTaskCondition(userData.getActivityId());
        if (!resetWealthScrollTaskCondition){
            log.error("玩家重置财神密卷condition任务失败!!!,活动id{},玩家id{}",userData.getActivityId(),userData.getUserId());
        }else {
            //设置最后刷新时间为当天零点
            userData.setLastRefreshConditionTime(DateHelper.getTodayZeroTimeStamp());
        }
    }

    /**
     * 重置玩家condition
     */
    public boolean resetWealthScrollTaskCondition(int activityId) {
        BaseActivityData baseActivityData = player.getModule(ActivityModule.class).getBaseActivityData(activityId);
        if (baseActivityData == null) {
            log.error("重置财神密卷condition失败,活动数据activityData为空!!!活动id为{}",activityId);
            return false;
        }
        List<BaseActivityCondition> baseActivityConditionList = baseActivityData.getBaseActivityConditionList();
        if (baseActivityConditionList == null || baseActivityConditionList.isEmpty()) {
            log.error("重置财神密卷condition失败,活动condition数据为空!!!活动id为{}",activityId);
            return false;
        }
        //重置玩家周常任务数据
        long modifyTime = System.currentTimeMillis() / 1000;
        for (BaseActivityCondition userActivityConditionData : baseActivityConditionList) {
            userActivityConditionData.setValue(BigInteger.ZERO);
            userActivityConditionData.setPreValue(BigInteger.ZERO);
            userActivityConditionData.setGetReward(false);
            userActivityConditionData.setModifyTime(modifyTime);
            userActivityConditionData.addTrigger(player);
        }
        return true;
    }


    /**
     * 检查是否生成玩家数据
     */
    public synchronized void checkWealthScrollUserData() {
        //没解锁不管
        if (!SystemOpenMgr.systemOpen(player, eSystemId.WealthScroll.getValue())){
            return;
        }

        //没活动开着不管了
        if (!WealthScrollActivityMgr.isNewWealthScrollOpening()) {
            return;
        }

        //如果老活动还在期限内 不生成了
        if(isOldSecretVolumeOpen()){
            return;
        }

        WealthScrollConfig config = WealthScrollActivityMgr.getConfig();
        if (config.getLoopEndNo() <= 0){
            log.error("新财神密卷配置的结束期数错误,活动id{}",config.getActivityId());
            return;
        }
        if (config.getLoopEndNo() < config.getLoopStartNo()){
            log.error("新财神密卷配置的结束期数错误,活动id{}",config.getActivityId());
            return;
        }
        if (userData == null || config.getActivityId() != userData.getActivityId()) {
            initUserData(config.getActivityId());
        }
    }

    /**
     * 老的财神密卷是否开启中
     */
    public boolean isOldSecretVolumeOpen(){
        return player.getModule(SecretVolumeModule.class).isNowInTime();
    }

    /**
     * 新的财神密卷是否在进行中
     * @return
     */
    public boolean isNewWealthScrollInTime(){
        if (userData == null){
            return false;
        }
        if (!WealthScrollActivityMgr.isNewWealthScrollOpening()){
            return false;
        }
        WealthScrollConfig config = WealthScrollActivityMgr.getConfig();

        return (userData.getStartTime() + (config.getSustainDay() * DateHelper.DAY_MILLIONS)) >= System.currentTimeMillis();
    }

    /**
     * 添加经验
     * @param exp
     */

    public void addWealthScrollExp(long exp){
        if (isNewWealthScrollInTime()){
            synchronized (this){
                userData.setExp(exp + userData.getExp());
                syncUserData();
            }
        }
    }

    @Override
    public boolean loadData() {
        if (WealthScrollActivityMgr.isNewWealthScrollOpening()){
            WealthScrollConfig config = WealthScrollActivityMgr.getConfig();

            userData = new UserCommonActivityDataDaoImpl<WealthScrollUserData>().getUserActivityData(WealthScrollUserData.class,config.getActivityId(),getUserId());
        }

        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (userData == null){
            return true;
        }

        if (userData.isInsertOption()){
            new UserCommonActivityDataDaoImpl<WealthScrollUserData>().add(userData);
        }else if (userData.isUpdateOption()){
            new UserCommonActivityDataDaoImpl<WealthScrollUserData>().update(userData);
        }

        return true;
    }

    @Override
    public void loginSendMsg() {
        //登陆前发吧
        init();
    }

    @Override
    public void afterLogin() {  //先拿出来 万一要用
        super.afterLogin();
    }

    /**
     * 领取奖励
     * @param activityId
     * @param taskIds
     * @return
     */

    public int getReward(int activityId, List<Integer> taskIds) {
        if (!isNewWealthScrollInTime()){
            return GameErrorCode.E_WEALTH_SCROLL_EXPIRED;
        }
        WealthScrollConfig config = WealthScrollActivityMgr.getConfig();
        if (config.getActivityId() != activityId) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }


        Property property = new Property();
        for (int taskId:taskIds){

            if (userData.hasGetReward(taskId)){
//                log.error("玩家尝试重复领奖,玩家id{},taskId{}",getUserId(),taskId);
                continue;
            }

            WealthScrollTaskConfig taskConfig = config.getTaskConfig(taskId);
            if (taskConfig == null){
                log.error("新财神密卷领奖奖励配置不存在,玩家id{},taskId{}",getUserId(),taskId);
                continue;
            }

            //看看是不是完成了
            if (!canComplete(taskConfig)){
                continue;
            }

            //先设置已领奖哦
            boolean success = userData.addHasGetReward(taskId);
            if (!success){
                log.error("新财神密卷领奖添加领奖记录失败,玩家id{},taskId{}",getUserId(),taskId);
                continue;
            }

            //用这里统一拿
            int no = userData.getNo();
            String reward = WealthScrollActivityMgr.getTaskRewardString(taskConfig, no);

            //加到奖励里面
            property.addProperty(PropertyHelper.parseStringToProperty(reward));

            //日志
            addGetRewardLog(taskConfig,activityId,no,reward,1);
        }
        if(property.isNothing()){
            return GameErrorCode.E_WEALTH_SCROLL_NO_REWARD;
        }
        WealthScrollProto.WealthScrollGetRewardResp.Builder builder = WealthScrollProto.WealthScrollGetRewardResp.newBuilder();
        builder.setRet(0);
        builder.setReward(PropertyHelper.parsePropertyToString(property));
        builder.setData(parseUserDataMsg(userData));

        player.sendPacket(ClientProtocol.U_WEALTH_SCROLL_GET_REWARD, builder);

        player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.WealthScroll,eLogMoneyType.WealthScrollTaskReward);

        return 0;
    }

    /**
     * 判断任务是否可以完成
     * @param taskConfig
     * @return
     */

    public boolean canComplete(WealthScrollTaskConfig taskConfig){
        if (userData == null){
            return false;
        }
        //如果不是这两个特殊类型 不走这里
        if (taskConfig.getCompleteType() != eGamePlayerEventType.WealthScrollRepeatBuyTime.getValue() &&
                taskConfig.getCompleteType() != eGamePlayerEventType.WealthScrollExpProcess.getValue()){
            return false;
        }

        int taskId = taskConfig.getId();
        List<Integer> completeParamList = taskConfig.getCompleteParamList();
        if (completeParamList == null || completeParamList.size() < 4){
            log.error("新财神密卷领奖奖励完成配置不存在,玩家id{},taskId{},当前期数{}",getUserId(),taskId,userData.getNo());
            return false;
        }
        //检查奖励配置
        if (taskConfig.getCompleteType() == eGamePlayerEventType.WealthScrollExpProcess.getValue() && !taskConfig.getRewardMap().containsKey(userData.getNo())){
            log.error("新财神密卷进度任务 领奖奖励完成奖励配置不存在,玩家id{},taskId{},当前期数{}",getUserId(),taskId,userData.getNo());
            return false;
        }
        if (taskConfig.getCompleteType() == eGamePlayerEventType.WealthScrollRepeatBuyTime.getValue() && StringUtils.isNullOrEmpty(taskConfig.getRewards())){
            log.error("新财神密卷复购 领奖奖励完成奖励配置不存在,玩家id{},taskId{},当前期数{}",getUserId(),taskId,userData.getNo());
            return false;
        }

        //判断是不是付费挡位才能完成
        int needBuyType = completeParamList.get(0);
        //如果不是免费的 玩家还没买 复购奖励和进度奖励都不给领取高级挡位
        if (needBuyType != eWealthScrollBuyLevel.free.getValue()){
            if (!userData.hasBuyLevel(needBuyType)){
                return false;
            }
        }
        //如果是进度奖励吧
        if (taskConfig.getCompleteType() == eGamePlayerEventType.WealthScrollExpProcess.getValue()){
            //判断经验到了没有
            int needExp = completeParamList.get(3);
            if (userData.getExp() < needExp){
                return false;
            }


        } else {        //另外这个就是新财神密卷复购次数
            //需要购买次数
            int needBuyTime = completeParamList.get(3);

            //如果次数不相等 不能完成
            if (userData.getRepeatBuyNum(needBuyType) != needBuyTime){
                return false;
            }
        }


        return true;
    }

    /**
     * 获取玩家数据
     * @param activityId
     * @return
     */

    public int getUserDataMsg(int activityId){
        if (!WealthScrollActivityMgr.isNewWealthScrollOpening()){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        if (userData == null || userData.getActivityId() != activityId){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        WealthScrollProto.WealthScrollUserDataMsg.Builder builder = parseUserDataMsg(userData);
        if (builder == null){
            return GameErrorCode.E_WEALTH_SCROLL_EXPIRED;
        }

        WealthScrollProto.WealthScrollGetUserDataResp.Builder resp = WealthScrollProto.WealthScrollGetUserDataResp.newBuilder();
        resp.setRet(0);
        resp.setData(builder);

        player.sendPacket(ClientProtocol.U_WEALTH_SCROLL_GET_USER_DATA, resp);

        return 0;
    }

    /**
     * 用户信息转msg
     * @param userData
     * @return
     */
    public WealthScrollProto.WealthScrollUserDataMsg.Builder parseUserDataMsg(WealthScrollUserData userData){
        if (userData == null){
            return null;
        }
        WealthScrollProto.WealthScrollUserDataMsg.Builder builder = WealthScrollProto.WealthScrollUserDataMsg.newBuilder();

        builder.setNo(userData.getNo());
        builder.setStartTime(userData.getStartTime());
        builder.setExp(userData.getExp());
        builder.addAllHasRewardTask(userData.getHasGetReward());
        builder.addAllBuyLevel(userData.getBuyType());
        Map<Integer, Integer> repeatBuyMap = userData.getRepeatBuyMap();

        for (Map.Entry<Integer,Integer> entry: repeatBuyMap.entrySet()){
            WealthScrollProto.WealthScrollRepeatBuyMsg.Builder repeatBuild = WealthScrollProto.WealthScrollRepeatBuyMsg.newBuilder();
            repeatBuild.setType(entry.getKey());
            repeatBuild.setBuyTime(entry.getValue());
            builder.addRepeatBuy(repeatBuild);
        }
        return builder;
    }



    /**
     * 是否可以购买
     */
    public int isCanRecharge(int extendParam){
        checkNextNo();
        if (!isNewWealthScrollInTime()){
            return GameErrorCode.E_WEALTH_SCROLL_EXPIRED;
        }
        eWealthScrollBuyLevel type = eWealthScrollBuyLevel.valueOf(extendParam);
        if (type == null){
            return GameErrorCode.E_WEALTH_SCROLL_MALL_ERROR;
        }
        if (userData.getBuyType().contains(extendParam)){
            return GameErrorCode.E_WEALTH_SCROLL_HAD_BUY;
        }
        return 0;

    }

    /**
     * 是否重复购买
     * @param extendParam
     * @return
     */
    public boolean isRepeatBuy(int extendParam){
        checkNextNo();
        eWealthScrollBuyLevel type = eWealthScrollBuyLevel.valueOf(extendParam);
        if (type == null|| type == eWealthScrollBuyLevel.free){
            log.error("新财神密卷商店额外参数配置错误,反通宝,玩家id{}",getUserId());
            return true;
        }
        if (!isNewWealthScrollInTime()){
            log.error("新财神密卷商店玩家没开启新类型,反通宝,玩家id{}",getUserId());
            return true;
        }
        if (userData.getBuyType().contains(extendParam)){
            log.error("新财神密卷商店重复购买,反通宝,玩家id{}",getUserId());
            return true;
        }

        return false;
    }

    /**
     * 添加购买的战令类型
     * @param mallParam
     */

    public void addUserBuyLevelByMallParam(int mallParam){
        if (!isNewWealthScrollInTime()){
            log.error("新财神密卷商店玩家没开启新类型,但是奖励已经给了,玩家id{}",getUserId());
            return;
        }
        checkNextNo();
        //加经验
        int advanceAddExp = WealthScrollActivityMgr.buyAdvanceAddExp(mallParam);
        addWealthScrollExp(advanceAddExp);
        //增加等级
        userData.addBuyLevel(mallParam);
        //升档
        WealthScrollConfig config = WealthScrollActivityMgr.getConfig();
        if (config != null){
            userData.addRepeatBuyNum(mallParam,1,config.getRepeatBuyMax());
        }
        syncUserData();
    }

    /**
     * 获取玩家数据
     * @return
     */
    public WealthScrollUserData getUserData() {
        return userData;
    }

    /**
     * 加日志 type1是领取 2是补发
     */
    public void addGetRewardLog(WealthScrollTaskConfig taskConfig,int activityId,int no,String reward,int getWay){
        LogWealthScrollGetReward log = new LogWealthScrollGetReward(activityId,getUserId(),no,taskConfig.getCompleteType(),taskConfig.getId(),reward,getWay);
        AutoLogMgr.add(log);
    }

}
